using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.IO;

namespace Sixeyed.CacheAdapter.Interfaces
{
    /// <summary>
    /// Represents a provider for a type of cache
    /// </summary>
    public interface ICacheProvider
    {
        /// <summary>
        /// Gets the type of the cache configuration object
        /// </summary>
        /// <returns></returns>
        Type GetConfigurationType();

        /// <summary>
        /// Initializes the cache instance
        /// </summary>
        /// <param name="configuration">Instance configuration</param>
        void Initialize(ICacheProviderConfiguration configuration);

        /// <summary>
        /// Returns whether the cache instance is initialized
        /// </summary>
        bool IsInitialized { get; }

        /// <summary>
        /// Returns an enumerator over all objects in the cache
        /// </summary>
        /// <returns></returns>
        IEnumerator GetEnumerator();
        
        /// <summary>
        /// Returns an object from the cache
        /// </summary>
        /// <param name="cacheKey">Cache key</param>
        /// <returns>Cached object, or null if not in cache</returns>
        object Get(string cacheKey);

        /// <summary>
        /// Returns a typed object from the cache
        /// </summary>
        /// <typeparam name="T">Object type</typeparam>
        /// <param name="cacheKey">Cache key</param>
        /// <returns>Cached object, or null if not in cache, or not of type T</returns>
        T Get<T>(string cacheKey) where T : class;

        /// <summary>
        /// Inserts/updates an object in the cache
        /// </summary>
        /// <param name="cacheKey">Cache key</param>
        /// <param name="serializableObject">Object to cache</param>
        void Put(string cacheKey, object serializableObject);

        /// <summary>
        /// Inserts/updates an object in the cache, with a specified lifespan
        /// </summary>
        /// <param name="cacheKey">Cache key</param>
        /// <param name="serializableObject">Object to cache</param>
        /// <param name="lifespan"></param>
        void Put(string cacheKey, object serializableObject, TimeSpan lifespan);

        /// <summary>
        /// Removes an object from the cache
        /// </summary>
        /// <param name="cacheKey">Cache key</param>
        void Remove(string cacheKey);

        /// <summary>
        /// Returns a cache key as a hash of the given object
        /// </summary>
        /// <param name="objectBuffer">Object byte array</param>
        /// <returns>Cache key</returns>
        string GetCacheKey(byte[] objectBuffer);

        /// <summary>
        /// Returns a cache key as a hash of the given object
        /// </summary>
        /// <param name="serializedObject">Serialiazed object</param>
        /// <returns>Cache key</returns>
        string GetCacheKey(string serializedObject);

        /// <summary>
        /// Returns a cache key as a hash of the given object
        /// </summary>
        /// <param name="serializableObject">Serialiazable object</param>
        /// <returns>Cache key</returns>
        string GetCacheKey(object serializableObject);

        /// <summary>
        /// Returns a random unique cache key
        /// </summary>
        /// <returns>Cache key</returns>
        string GetCacheKey();
    }
}
